import {computed, reactive, ref} from 'vue'
import {AuthUtil, EmptyUtil, MsgUtil, TreeUtil} from '@/utils'
import {CloseModelEvent} from "@/types";


/**
 *
 * 树形结构表格数据封装
 * */
export class TreePage {


    public title: string;

    public rowKey = 'id';

    public nameKey: string;


    protected permission: any


    public theme = reactive({
        bordered: {wrapper: true, cell: true, headerCell: true},
        size: "large",
        stripe: false,
        sticky: false,
        loading: true,
        hoverAble: true,
        layoutFixed: true,
        resizable: true

    })

    public dataSource = ref([])


    public expandedKeys = ref([])

    public treeMap = {
        topValue: '0',
        valueKey: 'id',
        parentKey: 'parentId'
    }

    public rowSelection = reactive({
        type: 'checkbox',
        showCheckedAll: true,
        checkStrictly: true
    });

    /**
     * @desc 加载数据的执行方法
     * */
    private fetchXhr: any

    /**
     * @desc 删除数据的执行方法
     * */
    private deleteXhr?: any

    /**
     * 服务初始化
     * @param title  实例标题
     * @param rowKey   数据的主键字段名称
     * @param nameKey 数据对应的标题字段名称
     * */

    constructor({title, rowKey, nameKey = null}) {
        this.title = title;
        this.rowKey = rowKey
        this.nameKey = nameKey
        this.expandedKeys.value = [];

    }


    /**
     * @desc 初始化列表查询执行方法
     * @param xhr 列表请求方法

     * */
    setFetchXhr(xhr) {
        this.fetchXhr = xhr
        return this
    }

    setPermission(permissionExpr: any) {
        this.permission = permissionExpr
        return this;
    }


    /**
     * @desc 初始化数据删除执行方法
     * @param xhr 执行数据删除的执行方法
     * */
    setDeleteXhr(xhr) {
        this.deleteXhr = xhr
        return this
    }


    /**
     * 设置当前对象的属性结构信息
     * @param topValue 最顶层的数据值
     * @param valueKey 数据值对应的Key名称
     * @param parentKey 上级值对应的Key名称
     * */
    public setTreeMap = (topValue, valueKey, parentKey) => {
        this.treeMap = {topValue, valueKey, parentKey}
        return this;
    }

    /**
     * @desc  调用数据请求方法
     * */
    onFetch = async (val='') => {
        if (typeof this.fetchXhr !== 'function') {
            MsgUtil.message('数据对象操作异常:当前实例尚未配置或初始化 【setFetchXhr】方法')
            return
        }

        if (this.permission !== undefined && typeof this.permission === 'object' && !AuthUtil.hasPermission(this.permission)) {
            MsgUtil.message(`访问当前数据查询接口需要：${JSON.stringify(this.permission)}权限`)
            return

        }
        this.theme.loading = true;
        try {
            const {data} = await this.fetchXhr(val)
            if (data.length > 0) {
                this.dataSource.value = TreeUtil.listToTree(data, this.treeMap.topValue, this.treeMap.valueKey, this.treeMap.parentKey)
            } else {
                this.dataSource.value = [];
            }


        } catch (e) {
            console.error(e)
        } finally {
            this.theme.loading = false;
        }
    }


    /**
     * @desc  删除对象
     * @param row 可选值：要删除的数据， 如果为空则删除选中的数据
     * @param callback  删除成功后执行的回调参数 不配置则重新加载数据
     *  */
    onDelete = (row: Record<string, any> = {}, callback: any = null) => {
        if (typeof this.deleteXhr !== 'function') {
            MsgUtil.message('数据对象操作异常:当前实例尚未配置或初始化 【deleteXhr】方法')
            return;
        }
        let msg: string
        const data = []
        if (EmptyUtil.isNotEmptyObject(row)) {
            const tip = this.nameKey ? `【${row[this.nameKey]}】` : ''
            msg = `确定要删除${tip}这条 ${this.title} 数据吗?`
            data.push(row[this.rowKey])
        } else {

            //   msg = `确定要批量删除选中的 ${data.length} 条 ${this.title} 数据吗?`
        }
        const sendAjax = async () => {
            const {message} = await this.deleteXhr(data)
            MsgUtil.notify('操作成功', message)
            if (callback != null) {
                callback()
            } else {

                await this.onFetch()
            }
        }
        MsgUtil.confirm(msg, sendAjax)
    }


    /**
     * 编辑弹窗控制层
     * */
    public editCtr = reactive({
        show: false,
        record: {},
        open: (e: Record<string, any> = {}) => {
            this.editCtr.show = true
            this.editCtr.record = e
        },
        close: async (e: CloseModelEvent) => {
            this.editCtr.show = false
            this.editCtr.record = {}
            if (e === 'NONE') return
            await this.onFetch()
        },
    })


    /**
     * 编辑弹窗控制层
     * */
    public readCtr = reactive({
        show: false,
        record: {},
        open: (e: Record<string, any> = {}) => {
            this.readCtr.show = true
            this.readCtr.record = e
        },
        close: async (e: CloseModelEvent) => {
            this.readCtr.show = false
            this.readCtr.record = {}
            if (e === 'NONE') return
            await this.onFetch()
        },
    })


    /**
     * 表格展开收起的切换方法
     * */



    public toggleTree() {

        if (EmptyUtil.isNotEmptyArray(this.expandedKeys.value)) {
            this.expandedKeys.value = []
        } else {
            const result = []
            // 获取展开的表格主键
            const getExpandValues = (list) => {
                list.forEach(item => {
                    if (item?.children !== undefined && EmptyUtil.isNotEmptyArray(item.children)) {
                        getExpandValues(item.children)
                        result.push(item[this.rowKey])
                    }
                })
                return result;
            }
            this.expandedKeys.value = getExpandValues(this.dataSource.value)
        }

    }


    public toggleText = computed(() => (this.expandedKeys.value.length > 0 ? '收起表格' : '展开表格'))

}

